﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Admin.NET.Core.Service;
using Microsoft.AspNetCore.Http;
using Furion.DatabaseAccessor;
using Furion.FriendlyException;
using Mapster;
using SqlSugar;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Admin.NET.Application.Entity;
namespace Admin.NET.Application;

/// <summary>
/// 物资分类服务 🧩
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupNameStore, Order = 100)]
public partial class StoreTypeService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<StoreType> _storeTypeRep;
    private readonly ISqlSugarClient _sqlSugarClient;

    public StoreTypeService(SqlSugarRepository<StoreType> storeTypeRep, ISqlSugarClient sqlSugarClient)
    {
        _storeTypeRep = storeTypeRep;
        _sqlSugarClient = sqlSugarClient;
    }

    /// <summary>
    /// 分页查询物资分类 🔖
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("分页查询物资分类")]
    [ApiDescriptionSettings(Name = "Page"), HttpPost]
    public async Task<SqlSugarPagedList<StoreTypeOutput>> Page(PageStoreTypeInput input)
    {
        input.Keyword = input.Keyword?.Trim();
        var query = _storeTypeRep.AsQueryable()
            .WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.Name.Contains(input.Keyword))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim()))
            .WhereIF(input.Status.HasValue, u => u.Status == input.Status)
            .LeftJoin<StoreType>((u, p) => u.Pid == p.Id)
            .Select((u, p) => new StoreTypeOutput
            {
                Id = u.Id,
                Name = u.Name,
                Pid = u.Pid,
                PDisplayName = $"{p.Name}",
                OrderNo = u.OrderNo,
                Status = (StatusEnum)u.Status,
                Remark = u.Remark,
                TenantId = u.TenantId,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserName = u.CreateUserName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserName = u.UpdateUserName,
                IsDelete = u.IsDelete,
            });
		return await query.OrderBuilder(input, "u.").ToPagedListAsync(input.Page, input.PageSize);
    }

    /// <summary>
    /// 获取物资分类详情 ℹ️
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("获取物资分类详情")]
    [ApiDescriptionSettings(Name = "Detail"), HttpGet]
    public async Task<StoreType> Detail([FromQuery] QueryByIdStoreTypeInput input)
    {
        return await _storeTypeRep.GetFirstAsync(u => u.Id == input.Id);
    }

    /// <summary>
    /// 增加物资分类 ➕
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("增加物资分类")]
    [ApiDescriptionSettings(Name = "Add"), HttpPost]
    public async Task<long> Add(AddStoreTypeInput input)
    {
        var entity = input.Adapt<StoreType>();
        if (await _storeTypeRep.IsAnyAsync(u => u.Name != null && u.Name == input.Name)) throw Oops.Oh("分类名称已存在");
        return await _storeTypeRep.InsertAsync(entity) ? entity.Id : 0;
    }

    /// <summary>
    /// 更新物资分类 ✏️
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("更新物资分类")]
    [ApiDescriptionSettings(Name = "Update"), HttpPost]
    public async Task Update(UpdateStoreTypeInput input)
    {
        if (await _storeTypeRep.IsAnyAsync(u => u.Id != input.Id && u.Name != null && u.Name == input.Name)) throw Oops.Oh("分类名称已存在");
        var entity = input.Adapt<StoreType>();
        await _storeTypeRep.AsUpdateable(entity)
        .ExecuteCommandAsync();
    }

    /// <summary>
    /// 删除物资分类 ❌
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("删除物资分类")]
    [ApiDescriptionSettings(Name = "Delete"), HttpPost]
    public async Task Delete(DeleteStoreTypeInput input)
    {
        var entity = await _storeTypeRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _storeTypeRep.FakeDeleteAsync(entity);   //假删除
        //await _storeTypeRep.DeleteAsync(entity);   //真删除
    }

    /// <summary>
    /// 批量删除物资分类 ❌
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("批量删除物资分类")]
    [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost]
    public async Task<int> BatchDelete([Required(ErrorMessage = "主键列表不能为空")]List<DeleteStoreTypeInput> input)
    {
        var exp = Expressionable.Create<StoreType>();
        foreach (var row in input) exp = exp.Or(it => it.Id == row.Id);
        var list = await _storeTypeRep.AsQueryable().Where(exp.ToExpression()).ToListAsync();
   
        return await _storeTypeRep.FakeDeleteAsync(list);   //假删除
        //return await _storeTypeRep.DeleteAsync(list);   //真删除
    }
    
    /// <summary>
    /// 设置物资分类状态 🚫
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("设置物资分类状态")]
    [ApiDescriptionSettings(Name = "SetStatus"), HttpPost]
    public async Task SetStoreTypeStatus(SetStoreTypeStatusInput input)
    {
        await _storeTypeRep.AsUpdateable().SetColumns(u => u.Status, input.Status).Where(u => u.Id == input.Id).ExecuteCommandAsync();
    }
    
    /// <summary>
    /// 获取下拉列表数据 🔖
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取下拉列表数据")]
    [ApiDescriptionSettings(Name = "DropdownData"), HttpPost]
    public async Task<Dictionary<string, dynamic>> DropdownData(DropdownDataStoreTypeInput input)
    {
        var pidData = await _storeTypeRep.Context.Queryable<StoreType>()
            .Select(u => new TreePOutput {
                Value = u.Id,
                Label = $"{u.Name}"
            }, true).ToTreeAsync(u => u.Children, u => u.Pid, null);
        // 筛选Status不为Disable
        pidData = pidData.Where(u => u.Status != StatusEnum.Disable).ToList();
        return new Dictionary<string, dynamic>
        {
            { "pid", pidData },
        };
    }
}
